<template>
  <div id="maskCanvas" ref="container" :style="{width:`${containerSize.width}px`,height:`${containerSize.height}px`}"
       @contextmenu.stop.prevent>
    <canvas ref="canvas" :class={brush:isDraw} :width="containerSize.width" :height="containerSize.height"
            @pointerdown.stop="canvasMouseDown" @click="isZoom||isDraw?null:$emit('Click')"/>

    <slide-element ref="slideElement"
                   :ContainerSize="containerSize"
                   :ElementStyle="{border:'1px solid',position:'absolute',top:0,cursor:'move'}"
                   :Size="{width:`${zoomRectangleSize.width}px`,height:`${zoomRectangleSize.height}px`}"
                   :Activated="true"
                   :LockWidth=true
                   :LockHeight=true
                   :KeyboardMove=false
                   v-if="isZoom && image">
      <canvas ref="zoomCanvas" :width="zoomRectangleSize.width" :height="zoomRectangleSize.height"/>
    </slide-element>
  </div>
</template>
<script>
  import SlideElement from './SlideElement'

  let remote = ''

  export default {
    name: 'MaskCanvas',
    props: {
      isDraw: { type: Boolean, default: false },
      isZoom: { type: Boolean, default: false },
      imageFile: { type: String, default: null },
      brushColor: { type: String, default: '#FF0000' },
      drawMode: { type: String, default: 'FreeLine' },
      brushWidth: { type: Number, default: 4 },
      zoomMultiples: { type: Number, default: 100 },
      trajectorys: {
        type: Array,
        default: function () {
          return []
        }
      },
      zoomLocation: {
        type: Object,
        default: function () {
          return null
        }
      },
      containerSize: {
        type: Object,
        default: function () {
          return { width: 200, height: 400 }
        }
      }
    },
    components: {
      'slide-element': SlideElement
    },
    data: function () {
      return {
        image: null,
        canvasContext: null,
        zoomContext: null,
        trajectory: [], // 标注轨迹
        pen: {
          cursor: `url(${process.browser ? '/static' : remote.getGlobal('staticPath')}/img/pen.png),auto`
        },
        zoomRectangleSize: { width: 0, height: 0 }
      }
    },
    watch: {
      imageFile: async function (n, o) {
        if (!n && this.zoomContext) this.zoomContext = null
        this.image = n ? await loadImage(n, this.containerSize) : null
      },
      trajectorys: function (n, o) {
        this.trajectory =
          n && Array.isArray(n) && n.length ? JSON.parse(JSON.stringify(n)) : []

        this.drawTrajectory(this.trajectory)
      },
      // zoomLocation: function(n, o) {
      //   this.zoomInImage(null, n);
      // },
      containerSize: function (n, o) {
        if ((n.width === o.width && n.height === o.height) || !n || n.width === undefined || n.height === undefined) {
          return
        }
        this.init()
      }
    },
    mounted: function () {
      this.init()
    },
    beforeDestroy: function () {
      this.canvasContext = null
      this.zoomContext = null
    },
    methods: {
      init: async function () {
        this.image = this.imageFile
          ? await loadImage(this.imageFile, this.containerSize)
          : null
        this.zoomRectangleSize = {
          width: this.containerSize.width * 0.5,
          height: this.containerSize.width * 0.5
        }

        this.$nextTick(function () {
          if (
            this.trajectorys &&
            Array.isArray(this.trajectorys) &&
            this.trajectorys.length
          ) {
            this.trajectory = JSON.parse(JSON.stringify(this.trajectorys))
            this.$nextTick(function () {
              this.drawTrajectory(this.trajectory)
            })
          }
          // if (this.zoomLocation) this.zoomInImage(null, this.zoomLocation);
        })
      },
      // 鼠标左键点击画布
      canvasMouseDown: function () {
        let self = this
        if (!self.isDraw) return
        let canvas = self.$refs.canvas
        if (!canvas) return
        let startLoc = { x: event.offsetX, y: event.offsetY }
        let locs = {
          type: this.drawMode,
          location: [{
            x: startLoc.x / canvas.offsetWidth,
            y: startLoc.y / canvas.offsetHeight
          }],
          isDraw: true
        }
        self.trajectory.push(locs)

        canvas.onpointermove = function () {
          // 获取鼠标位置坐标
          switch (locs.type) {
            case 'FreeLine':
              locs.location.push({
                x: event.offsetX / canvas.offsetWidth,
                y: event.offsetY / canvas.offsetHeight
              })
              break
            case 'StraightLine':
              locs.location[1] = {
                x: event.offsetX / canvas.offsetWidth,
                y: event.offsetY / canvas.offsetHeight
              }
              break
            case 'Rectangle':
              locs.location[0].w = (event.offsetX - startLoc.x) / canvas.offsetWidth
              locs.location[0].h = (event.offsetY - startLoc.y) / canvas.offsetHeight
              // locs.location[1] = {
              //   x: event.offsetX / canvas.offsetWidth,
              //   y: locs.location[0].y
              // };
              // locs.location[2] = {
              //   x: event.offsetX / canvas.offsetWidth,
              //   y: event.offsetY / canvas.offsetHeight
              // };
              // locs.location[3] = {
              //   x: locs.location[0].x,
              //   y: locs.location[2].y
              // };
              // locs.location[4] = {
              //   x: locs.location[0].x,
              //   y: locs.location[0].y
              // };
              break
            case 'Ellipse':
              if (startLoc.x !== event.offsetX || startLoc.y !== event.offsetY) {
                let x = event.offsetX - startLoc.x
                let y = event.offsetY - startLoc.y
                locs.location[0] = {
                  x: (startLoc.x + x / 2) / canvas.offsetWidth,
                  y: (startLoc.y + y / 2) / canvas.offsetHeight,
                  r: Math.abs(x > y ? x / 2 / canvas.offsetWidth : y / 2 / canvas.offsetHeight)
                }
              }
              break
          }
          // console.log(self.trajectory)
          self.drawTrajectory(self.trajectory)
        }
        canvas.onpointerup = () => {
          canvas.onpointerup = canvas.onpointermove = null
          self.$emit('DrawTrajectoryed', this.trajectory)
        }
        canvas.onpointerout = () => {
          canvas.onpointerout = canvas.onpointermove = null
          self.$emit('DrawTrajectoryed', this.trajectory)
        }
      },
      // 绘制标注轨迹
      drawTrajectory: function (trajectory) {
        let canvas = this.$refs.canvas
        if (!canvas) return
        if (!this.canvasContext) {
          // 创建上下文
          this.canvasContext = canvas.getContext('2d')
        } else {
          // 清空画布内容
          this.canvasContext.clearRect(
            0,
            0,
            canvas.offsetWidth,
            canvas.offsetHeight
          )
        }

        this.$nextTick(function () {
          // 设置画笔颜色、宽度
          this.canvasContext.strokeStyle = this.brushColor
          this.canvasContext.lineWidth = this.brushWidth
          trajectory.forEach(item => {
            // 绘制自由线条
            // if (item.isDraw) {
            if (item.type === 'Rectangle') {
              this.drawRectangle(canvas, item.location)
            } else if (item.type === 'Ellipse') {
              this.drawEllipse(canvas, item.location)
            } else {
              this.drawFreeLine(canvas, item.location)
            }
            // }
          })
        })
      },
      // 绘制自由线条
      drawFreeLine: function (canvas, locations) {
        if (!this.canvasContext || !canvas || !locations.length) return
        this.canvasContext.beginPath()
        locations.forEach(item => {
          let loc = {
            x: item.x * canvas.offsetWidth,
            y: item.y * canvas.offsetHeight
          }
          this.canvasContext.lineTo(loc.x, loc.y)
          this.canvasContext.moveTo(loc.x, loc.y)
        })
        this.canvasContext.closePath()
        this.canvasContext.stroke()
      },
      drawRectangle: function (canvas, locations) {
        if (!this.canvasContext || !canvas || !locations.length) return
        this.canvasContext.beginPath()
        locations.forEach(item => {
          let loc = {
            x: item.x * canvas.offsetWidth,
            y: item.y * canvas.offsetHeight,
            w: item.w * canvas.offsetWidth,
            h: item.h * canvas.offsetHeight
          }
          this.canvasContext.rect(loc.x, loc.y, loc.w, loc.h)
        })
        this.canvasContext.closePath()
        this.canvasContext.stroke()
      },
      drawEllipse: function (canvas, locations) {
        if (!this.canvasContext || !canvas || !locations.length) return

        this.canvasContext.beginPath()
        locations.forEach(item => {
          this.canvasContext.save()
          let loc = {
            x: item.x * canvas.offsetWidth,
            y: item.y * canvas.offsetHeight,
            r: item.r * (item.x > item.y ? canvas.offsetWidth : canvas.offsetHeight) /* - this.brushWidth * 2 */
          }

          loc.r = loc.r >= 0 ? loc.r : 0
          var ratioX = loc.x / loc.r
          var ratioY = loc.y / loc.r
          this.canvasContext.scale(ratioX, ratioY)
          this.canvasContext.arc(loc.x / ratioX, loc.y / ratioY, loc.r, 0, 2 * Math.PI, false)
          this.canvasContext.restore()
        })
        this.canvasContext.closePath()
        this.canvasContext.stroke()
      }
    }
  }

  /** @augments 加载图片对象 */
  function loadImage (url, containerSize) {
    return new Promise((resolve, reject) => {
      let image = new Image()
      image.src = url
      image.onload = function () {
        resolve(image)
      }
    })
  }
</script>
<style>
  #maskCanvas {
    z-index: 300;
    position: absolute;
    background-color: transparent;
    top: 0;
  }

  #maskCanvas .brush {
    cursor: url("~@/assets/img/SlideEditor/brush.png"), auto;
  }

  .container::-webkit-scrollbar-thumb {
    background-color: #267abb;
    border-radius: 4px;
  }

  .container::-webkit-scrollbar {
    width: 8px;
    height: 8px;
    background: #cbe2ee;
  }
</style>
